package napier.sadari;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class DrawSadariActivity extends Activity {
	
	drawSadariCanvas dsCanvas;
	long playerNumber;
	int mmove_eX=0;
	int mmove_mX=0;
	String[] playersName, playersGift;
	
	DialogInterface.OnClickListener nextBtn;
	
	AlertDialog.Builder ab1;
	Context context;
	
	
	int frontx, endx, fe_tx, endx_gap; 
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {    	    	
        super.onCreate(savedInstanceState);        
        dsCanvas = new drawSadariCanvas(this);
        setContentView(dsCanvas);
        Log.e("onCreate", "onCreate");
        
        playerNumber = getIntent().getLongExtra("playerNumber", 2);
        playersName = getIntent().getStringArrayExtra("playersName");
        playersGift = getIntent().getStringArrayExtra("playersGift");
        
        
        context = this;
        
        
        //ab1.show();
        
        Log.e("playerNumber", ""+playerNumber);
        Log.e("player1_name", ""+playersName[1]);
    }

    
    
    private class drawSadariCanvas extends View {
    	
    	int w, h, r=5, eventR=25;
    	int marginSide = 40;
    	int linegap;
    	int linegap_playing;
    	int pointgap;
    	int tpGap=0;
    	Canvas canvas;
    	Paint paint;
    	int nLine=0, nPoint=0, nELine=0;
    	List<PointNode> pointList = new ArrayList<PointNode>();
    	List<SadariLineNode> lineList = new ArrayList<SadariLineNode>();
    	List<eLineNode> eventLineList = new ArrayList<eLineNode>();
    	List<BtnNode> btnList = new ArrayList<BtnNode>();
    	List<ObjectNode> objList = new ArrayList<ObjectNode>();
    	
    	
    	boolean setConfig=true;
    	int touchEvent=0;
    	
    	float ex, ey;
    	
    	//int sPointNumber;
    	PointNode sPoint=null, ePoint=null;
    	

    	
    	public drawSadariCanvas(Context context){    		
    		super(context);
    		setBackgroundColor(R.color.canvasBgColor);
    		Log.e("a2", getWidth() + " " + getHeight());    		
    		
    		
    	}
    	
    	
    	int thread_flag = 0;
    	Thread thread;
    	
    	
		
    	
    	@Override
    	protected void onDraw(Canvas canvas){
    		// TODO onDraw
    		
    		int i;
    		Random ran = new Random();
    		if(setConfig){    			
    			paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        		
        		//canvas.drawColor(R.color.canvasBgColor);
    			canvas.drawColor(getResources().getColor(R.color.canvasBgColor));
        		
        		w = getWidth();
    			h = getHeight();
    			pointgap = h/4;
    			//linegap = w/2 - 30;
    			linegap = (int)((w-marginSide*2)/(playerNumber-1));
    			frontx = 0;
    			endx = 0;
    			endx_gap = (int) ((linegap * (playerNumber -1) + marginSide*2) - w);
    			
    			this.canvas = canvas;
    			
    			for(i=0; i<playerNumber; i++){
    				addLine(linegap*i+marginSide);
    			}
    			
    			for(i=0; i<playerNumber; i++){
    				ObjectNode o = new ObjectNode(linegap*i+marginSide,marginSide,Color.rgb(ran.nextInt()%255, ran.nextInt()%255, ran.nextInt()%255));
        			objList.add(o);
    			}
    			
    			
    			
    			
    			nextBtn = new DialogInterface.OnClickListener() {					
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						
						Intent aIntent = new Intent(DrawSadariActivity.this, ResultActivity.class);        		        		
		        		startActivity(aIntent);
		        		finish();
					}
				};

    			
    			
    			addBtn(w-100,0,w,30, 100);
    			
    			setConfig = false;
    		}
    		
    		
    		
    		
    		/////Draw Button
    		canvas.drawColor(getResources().getColor(R.color.canvasBgColor));
    		paint.setColor(getResources().getColor(R.color.btnColor));
    		for(i=0; i<btnList.size(); i++){
    			int tx = btnList.get(i).getX();
    			int ty = btnList.get(i).getY();
    			int tw = btnList.get(i).getW();
    			int th = btnList.get(i).getH();
    			canvas.drawRect(tx, ty, tw, th, paint);
    		}
    		
    		
    		
    		
    		
    		
    		//canvas.drawColor(getResources().getColor(R.color.canvasBgColor));
    		paint.setColor(getResources().getColor(R.color.basicLine));  		
    		    		
    		//canvas.drawR
    		
    		
    		//canvas.drawLine(0, 0, tThread.x, tThread.y, paint);    			
    		
    		//canvas.drawLine(0, 0, tx, tx, paint);
    		
    		for(i=0; i<lineList.size(); i++){
    			int x = lineList.get(i).getXPosition();
    			canvas.drawLine(x+mmove_eX+mmove_mX, 40, x+mmove_eX+mmove_mX, h-10, paint);
    		}
    		for(i=0; i<eventLineList.size(); i++){
    			int spn = eventLineList.get(i).getStartPointNumber();
    			int epn = eventLineList.get(i).getEndPointNumber();
    			canvas.drawLine(pointList.get(spn).getXPosition()+mmove_eX+mmove_mX, pointList.get(spn).getYPosition(),
    							pointList.get(epn).getXPosition()+mmove_eX+mmove_mX, pointList.get(epn).getYPosition(), paint);
    		}
    		for(i=0; i<pointList.size(); i++){
    			int x = pointList.get(i).getXPosition();
    			int y = pointList.get(i).getYPosition();
    			
    			if(pointList.get(i).getState() == 1){
    				if(ePoint != null)
    					paint.setColor(getResources().getColor(R.color.event_ok));
    				else
    					paint.setColor(getResources().getColor(R.color.eventPoint));
    				
    				canvas.drawCircle(x+mmove_eX+mmove_mX, y, eventR-10, paint);
    				paint.setColor(getResources().getColor(R.color.basicLine));
    			} else {
    				canvas.drawCircle(x+mmove_eX+mmove_mX, y, r, paint);
    			}
    		}
    		
    		
    		
    		
    		
    		
    		
    		/////Move Object
    		for(i=0; i<objList.size(); i++){
    			int tx = objList.get(i).getX();
    			int ty = objList.get(i).getY();
    			int tc = objList.get(i).getColor();   
    			
    			paint.setColor(tc);
    			canvas.drawCircle(tx+mmove_eX+mmove_mX, ty, 15, paint);
    		}
    		
    		
    		
    		
    		
    		switch(touchEvent){
    		case 0:
    			break;
    		case 1:
    			paint.setStrokeWidth(3);
    			if(ePoint != null)
    				paint.setColor(getResources().getColor(R.color.event_ok));
    			else
    				paint.setColor(getResources().getColor(R.color.eventLine));
    			
    			canvas.drawLine(sPoint.getXPosition()+mmove_eX+mmove_mX, sPoint.getYPosition(), ex, ey, paint);
    			paint.setStrokeWidth(1);
    			break;
    		}
    		
    		
    		//paint.setColor(Color.YELLOW);
    		//canvas.drawCircle(x, y, r, paint);
    		
    		
    		
    		
    		super.onDraw(canvas);
    		
    	}
    	
    	
    	private void addLine(int x){
    		
    		SadariLineNode l = new SadariLineNode(nLine++,x);
    		lineList.add(l);
    		
    		for(int i=1; i<=4; i++){
    			PointNode p = new PointNode(nLine, nPoint++, x, pointgap*i-20-(tpGap+1)%(pointgap/2));
    			pointList.add(p);
    		}
    		tpGap += pointgap/4;
    		
    	}
    	
    	private void addBtn(int x, int y, int w, int h, int kind){
    		
    		BtnNode b = new BtnNode(x,y,w,h,kind);
    		btnList.add(b);    		
    	}

    	
    	@Override
    	public boolean onTouchEvent(MotionEvent event) {
    		// TODO Auto-generated method stub
    		
    		if(thread_flag == 10 && event.getAction() == MotionEvent.ACTION_DOWN){
    			ab1 = new AlertDialog.Builder(context);        
		        ab1.setMessage("Is ok?\nk1 : 1\n k2 : \2");
		        ab1.setPositiveButton("ok", nextBtn);		        
		        ab1.show();
		        
		        return true;
    		}
    		
    		    		    		
    		float ex = event.getX();
    		float ey = event.getY();
//    		x = ex;
//    		y = ey;

    		
    		if(thread_flag == 1) return true;
    		
    		int btnKind = checkBtn(ex, ey);
    		if(btnKind!=0){
    			
    			
    			
	    		switch(btnKind){
	    		case 100:
	    			Log.e("moveObj",""+btnKind);
	    			runThread();
	    			break;
	    		}
	    		
	    		return true;
    		}
    		
    		
//    		paint.setColor(Color.YELLOW);
//			canvas.drawCircle(ex, ey, r, paint);
//			Log.e("exy",ex+" / "+ey);
    		
    		if(event.getAction() == MotionEvent.ACTION_UP){
    			

    			
    			if(touchEvent == 0){
    				if(mmove_eX != 0)
    					mmove_mX = mmove_eX+mmove_mX;
    				
    				return false;
    			}
    			
    			
//    			x = ex;
//        		y = ey;
//        		Log.e("exyUp",ex+" / "+ey);
    			
    			if(ePoint != null){	        		
	        		eLineNode el = new eLineNode(nELine++, sPoint.getPointNumber(), ePoint.getPointNumber());
	        		eventLineList.add(el);
	        		ePoint.setState(0);
	        		ePoint = null;
	        	}    			
	        	
	        	sPoint.setState(0);	        		
	        	sPoint = null;
	        	
	        	touchEvent = 0;
	        	
    			
    			
    		}else if(event.getAction() == MotionEvent.ACTION_MOVE){
    			
    			
        		
    			if(touchEvent == 0){
    				
    				return false;
    				
/*    				
    				
    				if(((int)(ex - this.ex)>=1 || (int)(ex - this.ex)<=-1)
   // 						&& frontx >= 0 && endx >= w
    						){    					    					
    					  
    					Log.e("w / endx / mmove_mX",w + " / " + endx + " / " + mmove_mX);
    					
    					if(frontx + fe_tx - ex <= 0){
    						frontx = 0;
    						//endx = w;
    						mmove_eX = 0;
    						mmove_mX = 0;
    						invalidate();    						
    						return false;
    					}
    					else if (endx + fe_tx - ex >= endx_gap) {
    						mmove_eX = 0;
    						mmove_mX = -endx_gap;    						
    						endx = endx_gap;
    						invalidate();
    						Log.e("22","2: " + endx + " / " + (endx + fe_tx - ex) + " / " + endx_gap);
    						return false;
    					}
    					frontx += (fe_tx - ex);
    					endx += (fe_tx - ex);
    					
    					mmove_eX = (int)(ex - this.ex);
    					//Log.e("w / endx / mmove_mX",w + " / " + endx + " / " + mmove_mX);
    					fe_tx = (int)ex;
	    				invalidate();
    				}
    				return false;
*/
    				
    			}
    			
    			this.ex = ex;
        		this.ey = ey;
    			
//    			x = ex;
//        		y = ey;
//        		Log.e("exyMove",ex+" / "+ey);
        		
        		
    			for(int i=0; i<pointList.size(); i++){
    				PointNode tPoint = pointList.get(i);
    				int tx = tPoint.getXPosition();
    				int ty = tPoint.getYPosition();
    				
 //   				Log.e("exyDown _For",ex+" / "+ey); 
    				if(checkNearPoint(ex, ey, tx, ty)
    						&& checkNearLine(tPoint.getLineNumber(), sPoint.getLineNumber())    						
    						&& checkContainPoint(tPoint) ){    					
    					tPoint.setState(1);
    					ePoint = tPoint;
    					//ePoint = tPoint;
    					//touchEvent = 2;
    					
    					
    				} else if (!tPoint.equals(sPoint) && tPoint.getState()==1){
    					ePoint = null;
    					tPoint.setState(0);
    				}
    				
    			}
        		
    		} else if(event.getAction() == MotionEvent.ACTION_DOWN){
//    			x = ex;
//        		y = ey;
    			this.ex = ex;
        		this.ey = ey;
        		mmove_eX = 0;
        		fe_tx = (int)ex;
//       		Log.e("exyDown",ex+" / "+ey);        		
    			for(int i=0; i<pointList.size(); i++){
    				PointNode tPoint = pointList.get(i);
    				int tx = tPoint.getXPosition();
    				int ty = tPoint.getYPosition();
    				
 //   				Log.e("exyDown _For",ex+" / "+ey); 
    				if(checkNearPoint(ex, ey, tx, ty) && checkContainPoint(tPoint)){    					
    					tPoint.setState(1);
    					sPoint = tPoint;
    					touchEvent = 1;    					
    					
    					
//    					Log.e("exyDown _checkPoint"," / "+touchEvent);
    				}
    				
    			}
    			        		
    		}

    		

    		
    		
    		    		
    		invalidate();
    		return true;
    	}

    	
    	private boolean checkNearPoint(float eventX, float eventY, int pointX, int pointY){
    		
    		if(eventX >= pointX+mmove_eX+mmove_mX-eventR && eventX <= pointX+mmove_eX+mmove_mX+eventR && eventY >= pointY-eventR && eventY <= pointY+eventR){
    			return true;
    		}
    		
    		return false;
    	}
    	
    	
    	private boolean checkContainPoint(PointNode p){
    		
    		for(int i=0; i<eventLineList.size(); i++){
    			if( pointList.get(eventLineList.get(i).getStartPointNumber()).equals(p)
    					|| pointList.get(eventLineList.get(i).getEndPointNumber()).equals(p))
    			return false;
    		}
    		
    		return true;
    	}
    	
    	private boolean checkNearLine(int line1, int line2)
    	{
    		int d = Math.abs(line1 - line2);
    		
    		if(d == 1){
    			return true;
    		}
    		
    		return false;
    	}
    	
    	private int checkBtn(float ex, float ey){
    		
    		for(int i=0; i<btnList.size(); i++){
    			int tx = btnList.get(i).getX();
    			int ty = btnList.get(i).getY();
    			int tw = btnList.get(i).getW();
    			int th = btnList.get(i).getH();
    			int k = btnList.get(i).getKind();
    			
    			if(ex >= tx && ex <= tw && ey >= ty && ey <= th){
    				return k;
    			}    			
    			
    		}    		
    		
    		
    		
    		return 0;
    	}
    	
    	
    	
    	
    	private void runThread(){    		
    		//TODO Thread
    		    		
			if(thread_flag == 0){
				
				if(thread != null)thread.interrupt();
				thread = null;
				
				thread_flag = 1;				
				translateObjects();
				
				thread = new Thread(new Runnable() {
					
					public void run() {
						

						boolean reach=true;
						
						
						while(reach){
							//canvas.drawLine(0, 0, j, j, paint);
							
							int sleepTime=10;
							
							
							if(thread_flag == 0) break;
							
							
							for(int i=0; i<objList.size(); i++){
								
								int nx=0, ny=0;
								float t = 80;
								
								float ex=0, ey=0;
								int p1x=0,p1y=0, p2x=0,p2y=0;
								int sTime=1;
								boolean isE = false;
								
								ex = objList.get(i).ex;
								ey = objList.get(i).ey;
								p1x = objList.get(i).p1x;
								p1y = objList.get(i).p1y;
								p2x = objList.get(i).p2x;
								p2y = objList.get(i).p2y;
								sTime = objList.get(i).sTime;
								isE = objList.get(i).isE;
								
								
								int x = objList.get(i).getX();
								int y = objList.get(i).getY();
								nx = x;
								
								if(y+1 == h-10){
									ny = y;
									objList.get(i).setState(1);
								}else{
									ny = y+1;
								}
								
								
								
								for(int i2=0; i2<eventLineList.size(); i2++){
									if(isE) break;
									
						    		int spn = eventLineList.get(i2).getStartPointNumber();
						    		int epn = eventLineList.get(i2).getEndPointNumber();
						    		PointNode p1 = pointList.get(spn);
						    		PointNode p2 = pointList.get(epn);
						    		
						    		
						    		if(p1.getXPosition() == x && p1.getYPosition() == y){
						    			isE = true;	
						    			ex = (p2.getXPosition()-p1.getXPosition())/t;
						    			ey = (p2.getYPosition()-p1.getYPosition())/t;
						    			
						    			p1x = p1.getXPosition();
						    			p1y = p1.getYPosition();
						    			p2x = p2.getXPosition();
						    			p2y = p2.getYPosition();

						    			//sleepTime = 50;
						    			//Log.e("p1,p2//1",p2.getYPosition()+" / "+ p1.getYPosition());
						    			break;
						    			
						    			//if(sTime==10) sTime=0;
						    		} else if(p2.getXPosition() == x && p2.getYPosition() == y){
						    			isE = true;	
						    			ex = (p1.getXPosition()-p2.getXPosition())/t;
						    			ey = (p1.getYPosition()-p2.getYPosition())/t;
						    			
						    			p1x = p2.getXPosition();
						    			p1y = p2.getYPosition();
						    			p2x = p1.getXPosition();
						    			p2y = p1.getYPosition();

						    			//sleepTime = 50;
						    			//Log.e("p1,p2//1",p2.getYPosition()+" / "+ p1.getYPosition());
						    			break;
						    			
						    			//if(sTime==10) sTime=0;
						    		}					    			
					    		}
								if(isE){
									//Log.e("1",ny+" / "+ ey);
									nx = p1x + (int)(ex*sTime);									
									ny = p1y + (int)(ey*sTime);	
									sTime++;
									//Log.e("2",ny+" / "+ ey);
								}
								
								if(sTime == t+1){
									isE = false;
									sTime = 1;
									nx = p2x;
									ny = p2y+1;
									sleepTime = 10;
								}
								
								//Log.e("p1,p2//1",nx+" / "+ ny);
								objList.get(i).setX(nx);
								objList.get(i).setY(ny);
								
								objList.get(i).ex = ex;
								objList.get(i).ey = ey;
								objList.get(i).p1x = p1x;
								objList.get(i).p1y = p1y;
								objList.get(i).p2x = p2x;
								objList.get(i).p2y = p2y;
								objList.get(i).sTime = sTime;
								objList.get(i).isE = isE;
							}
														

							
							
							
							
							
							
							try{
				    			Thread.sleep(sleepTime);
				    		}catch(InterruptedException e){
				    			Log.e("InterruptedException",""+e);
				    		}
				    		//invalidate();
				    		postInvalidate();
				    		//Log.e("thread",j+"");
				    		
				    		
				    		
				    		for(int i=0; i<objList.size(); i++){
								reach = false;
								if(objList.get(i).getState() == 0){
									reach = true;
									break;
								}
							}
				    		
				    		
						}//End of While						
						
						Log.e("end While","end Thread");
						thread_flag = 10;
						linegap = w/2 - marginSide;
						
		        		
		        		
						//thread.stop();
						//thread.destroy();
						//thread.setDaemon(false);
					}
					
				});   		
				
				//if(thread_flag) thread.destroy();
				thread.setDaemon(true);
				thread.start();	    		
				//thread.stop();
				
				
			}
		
    	}
    	
    	
    	void translateObjects(){
    		
    		int i;    		
    		int tgap = (w-marginSide*2)/((int)playerNumber-1);
    		mmove_eX = 0;
    		mmove_mX = 0;
    		
    		for(i=0; i<lineList.size(); i++){
    			lineList.get(i).setXPosition(tgap*i+marginSide);    			
    		}    		
    		for(i=0; i<pointList.size(); i++){	
    			pointList.get(i).setXPosition(tgap*(i/4)+marginSide);    			
    		}    		
    		for(i=0; i<objList.size(); i++){
    			objList.get(i).setX(tgap*i+marginSide);
    		}
    		
    	}
    }
    


    
    
    class PointNode{
    	
    	private int lineNumber;
    	private int pointNumber;
    	private int x;
    	private int y;
    	private int state;
    	
    	public PointNode(int nline, int npoint, int x, int y){
    		lineNumber = nline;
    		pointNumber = npoint;
    		this.x = x;
    		this.y = y;
    		state = 0;
    	}
    	
    	public void setLineNumber(int n){
    		lineNumber = n;
    	}
    	
    	public void setXPosition(int x){
    		this.x = x;
    	}
    	
    	public void setYPosition(int y){
    		this.y = y;
    	}
    	
    	public void setState(int s){
    		state = s;
    	}
    	
    	public int getLineNumber(){
    		return lineNumber;
    	}
    	
    	public int getXPosition(){
    		return x;
    	}
    	
    	public int getYPosition(){
    		return y;
    	}
    	
    	public int getState(){
    		return state;
    	}
    	
    	public void setPointNumber(int n){
    		pointNumber = n;
    	}
    	
    	public int getPointNumber(){
    		return pointNumber;
    	}
    	
    }
    
    
    class SadariLineNode{
    	private int lineNumber;    	
    	private int x;
    	
    	public SadariLineNode(int n, int x){
    		lineNumber = n;
    		this.x = x;
    	}
    	
    	public void setLineNumber(int n){
    		lineNumber = n;
    	}
    	
    	public void setXPosition(int x){
    		this.x = x;
    	}
    	
    	public int getLineNumber(){
    		return lineNumber;
    	}
    	
    	public int getXPosition(){
    		return x;
    	}
    }
    
    
    class eLineNode{
    	private int lineNumber;    	
    	private int sp;
    	private int ep;
    	
    	public eLineNode(int n, int sPointNum, int ePointNum){
    		lineNumber = n;
    		sp = sPointNum;
    		ep = ePointNum;
    	}
    	
    	public void setLineNumber(int n){
    		lineNumber = n;
    	}
    	
    	public int getLineNumber(){
    		return lineNumber;
    	}    	
    	
    	public void setStartPointNumber(int sPointNum){
    		sp = sPointNum;
    	}
    	
    	public int getStartPointNumber(){
    		return sp;
    	}    	
    	
    	public void setEndPointNumber(int ePointNum){
    		ep = ePointNum;
    	}
    	
    	public int getEndPointNumber(){
    		return ep;
    	}
    	
    	
    }
    
    
    class BtnNode{
    	private int x;
    	private int y;
    	private int w;
    	private int h;
    	private int k; 
    	
    	public BtnNode(int x, int y, int w, int h, int kind){
    		this.x = x;
    		this.y = y;
    		this.w = w;
    		this.h = h;
    		this.k = kind;
    	}
    	
    	public void setX(int x){
    		this.x = x;    		
    	}
    	
    	public int getX(){
    		return x;
    	}
    	
    	public void setY(int y){
    		this.y = y;    		
    	}
    	
    	public int getY(){
    		return y;
    	}
    	
    	public void setW(int w){
    		this.w = w;    		
    	}
    	
    	public int getW(){
    		return w;
    	}
    	
    	public void setH(int h){
    		this.h = h;    		
    	}
    	
    	public int getH(){
    		return h;
    	}
    	
    	public void setKind(int k){
    		this.k = k;    		
    	}
    	
    	public int getKind(){
    		return k;
    	}
    }
    
    class ObjectNode{
    	private int x;
    	private int y;    	
    	private int c;
    	private int s;
    	
    	
    	public float ex=0, ey=0;
		public int p1x=0,p1y=0, p2x=0,p2y=0;
		public int sTime=1;
		public boolean isE = false;
    	
    	public ObjectNode(int x, int y, int color){
    		this.x = x;
    		this.y = y;
    		this.c = color;
    		s = 0;
    	}
    	
    	public void setX(int x){
    		this.x = x;    		
    	}
    	
    	public int getX(){
    		return x;
    	}
    	
    	public void setY(int y){
    		this.y = y;    		
    	}
    	
    	public int getY(){
    		return y;
    	}
    	
    	public void setColor(int color){
    		this.c = color;
    	}
    	
    	public int getColor()
    	{
    		return c;
    	}
    	
    	public void setState(int state){
    		this.s = state;
    	}
    	
    	public int getState()
    	{
    		return s;
    	}

    }


	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub		
		Log.e("onDestroy", "DrawSadariActivity onDestroy");		
		super.onDestroy();
	}
    
}